
from sqlalchemy import and_
from datetime import datetime

from app.dao import Session
from app.models import Group,User, Hub, GroupDetail
from app.parameter import  QueryHubsParam,CreateHubParam,DeleteHubParam,QueryHubParam
from app.utils import Response, signatureDecode,signatureEncode
from app.constant import ERRORCODE
from utils import DEBUG,ERROR
from store import VectorStore
from embeddings import embeddingPool

class HubService():
    @staticmethod
    def judgeGroup(userId :int, groupId :int, session):
        return session.query(Group).filter(and_(Group.user_id == userId, Group.group_id == groupId)).first()

    @staticmethod
    def judgeHub(userId :int, hubId :int, session = None):
        if session != None:
            return session.query(Hub).join(Group, Hub.group_id == Group.group_id).filter(and_(Hub.id == hubId, Group.user_id == userId)).first()
        with Session() as session:
            return session.query(Hub).join(Group, Hub.group_id == Group.group_id).filter(and_(Hub.id == hubId, Group.user_id == userId)).first()
        
    @staticmethod
    def queryHubs(queryHubsParam :QueryHubsParam, userId: int):
        try:
            with Session() as session:
                group = HubService.judgeGroup(userId, queryHubsParam.groupId, session)
                if group == None:
                    return Response(ERRORCODE.REQUEST_NOT_FOUND_ERROR, message="not found group!")
                
                hubs = session.query(Hub).filter(Hub.group_id == queryHubsParam.groupId).all()
                hubs = [hub.to_dict() for hub in hubs]
                
                return Response(ERRORCODE.RESPONSE_SUCCESS, hubs)
            
        except Exception as e:
            ERROR(e)
            return Response(ERRORCODE.RESPONSE_DATABASE_OPERATION_ERROR, None)
    
    @staticmethod
    def createHub(createHubParam :CreateHubParam, userId: int, EmbeddingModel = None):
        try:
            with Session() as session:
                
                group = HubService.judgeGroup(userId, createHubParam.groupId, session)
                if group == None:
                    return Response(ERRORCODE.REQUEST_NOT_FOUND_ERROR, message="not found group!")
                group = group.to_dict()
                print(group)
                if group["permission"] < 2:
                     return Response(ERRORCODE.REQUEST_HAVE_NO_PERMISSION, message="Have not permission!")
                
                hub = Hub(group_id = createHubParam.groupId, hub_name = createHubParam.hubName, \
                    description=createHubParam.description, user_id = userId, \
                        overlap = createHubParam.overlap,
                        chunk_size = createHubParam.chunkSize
                        )
                session.add(hub)
                session.flush()
                
                hub_id = hub.id
                dims = 0
                
                if EmbeddingModel == None:
                    dims = embeddingPool.getDims()
                else:
                    dims = EmbeddingModel.getDims()
                
                store = VectorStore(hub_id, createHubParam.chunkSize, dims)
                store.create()
                
                session.commit()
                return Response(ERRORCODE.RESPONSE_SUCCESS)
            
        except Exception as e:
            ERROR(e)
            return Response(ERRORCODE.RESPONSE_DATABASE_OPERATION_ERROR, None)
        
    @staticmethod
    def deleteHub(deleteHubParam :DeleteHubParam, userId: int):
        try:
            with Session() as session:
                # 查询
                hub = session.query(Hub)\
                    .filter(and_(Hub.id == deleteHubParam.hubId, Hub.user_id == deleteHubParam.userId)).first()
                if hub == None:
                    return Response(ERRORCODE.REQUEST_HAVE_NO_PERMISSION)
                
                session.query(Hub)\
                    .filter(and_(Hub.id == deleteHubParam.hubId, Hub.user_id == deleteHubParam.userId)).delete()
                session.commit()
                return Response(ERRORCODE.RESPONSE_SUCCESS,hub)
        except Exception as e:
            ERROR(e)
            return Response(ERRORCODE.RESPONSE_DATABASE_OPERATION_ERROR, None)
    
    @staticmethod
    def queryAllHub(userId: int):
        try:
            with Session() as session:
                # 查询
                results = session.query(Group, Hub, GroupDetail)\
                    .join(Hub, Hub.group_id == Group.group_id)\
                    .join(GroupDetail, Group.group_id == GroupDetail.id)\
                    .filter(Group.user_id == userId).order_by(Group.id).all()
                
                DEBUG(results)
                
                if results == None or len(results) == 0:
                    return Response(ERRORCODE.RESPONSE_SUCCESS, [])

                data = []
                for result in results:
                    group = result[0].to_dict()
                    hub = result[1].to_dict()
                    groupDetail = result[2].to_dict()
                    
                    tmp = {"group_id": groupDetail["id"], "hub_id": hub["id"], \
                        "hub_name": hub["hub_name"], "group_name": groupDetail["group_name"]}
                    data.append(tmp)
                    
                return Response(ERRORCODE.RESPONSE_SUCCESS,data)
        except Exception as e:
            ERROR(e)
            return Response(ERRORCODE.RESPONSE_DATABASE_OPERATION_ERROR, None)
    # 查询特定群组成员
    @staticmethod
    def queryHub(queryHubParam :QueryHubParam, userId):
        try:
            with Session() as session:
                res = HubService.judgeHub(userId, queryHubParam.hubId, session)
                DEBUG(res)
                if res == None:
                    return Response(ERRORCODE.REQUEST_HAVE_NO_PERMISSION)
                
                data = session.query(Hub).join(GroupDetail, Hub.group_id == GroupDetail.id).\
                    join(User, Hub.user_id == User.id).filter(Hub.id == queryHubParam.hubId)\
                        .with_entities(Hub.hub_name, Hub.description, Hub.create_at,User.nickname, User.avatar,\
                                       GroupDetail.group_name, Hub.chunk_size, Hub.overlap).first();
                DEBUG(data)
                
                res = {}
                res['hub_name'] = data[0]
                res['description'] = data[1]
                res['create_at'] = str(data[2])
                res['nickname'] = data[3]
                res['avatar'] = data[4]
                res['group_name'] = data[5]
                res["overlap"] = data[-1]
                res["chunk_size"] = data[-2]
                return Response(ERRORCODE.RESPONSE_SUCCESS, res)
        except Exception as e:
            ERROR(e)
            return Response(ERRORCODE.RESPONSE_DATABASE_OPERATION_ERROR, None)